package com.tengju.bff.interfaces.manage.crm.motivation.facade;

import com.beust.jcommander.internal.Lists;
import com.google.common.collect.Maps;
import com.tengju.bff.interfaces.manage.crm.motivation.form.GetActivityPerformanceObjectiveListForm;
import com.tengju.bff.interfaces.manage.crm.motivation.form.GetPerformanceObjectiveCommonListForm;
import com.tengju.bff.interfaces.shared.ColumnVO;
import com.tengju.bff.interfaces.shared.PageResultVO;
import com.tengju.bff.interfaces.shared.TableVO;
import com.tengju.motivation.application.activity.MotivationActivityConfigService;
import com.tengju.motivation.application.performance.dto.ChunMiaoPlanUserTargetForm;
import com.tengju.motivation.domain.model.performance.MotivationActivityConfig;
import com.tengju.motivation.domain.model.performance.*;
import com.tengju.motivation.domain.shared.DateUtil;
import com.tengju.motivation.domain.shared.PerformanceObjectiveType;
import com.tengju.motivation.domain.shared.Year;
import com.tengju.user.application.user.UserDocumentService;
import com.tengju.user.domain.model.doc.UserDocument;
import com.tengju.user.domain.model.user.StarLevelEnum;
import com.tengju.user.domain.model.user.UserIdCode;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: 李大仙
 * @date: 2021/7/23 4:07 下午
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class MotivationPerformanceObjectiveFacade {

    private final PerformanceObjectiveRepository performanceObjectiveRepository;
    private final MotivationActivityConfigService activityConfigService;
    private final UserDocumentService userDocumentService;

    /**
     * 查询春苗计划目标值
     *
     * @param idCode      会员id
     * @param dateForYear 日期：年
     * @return {@link ChunMiaoPlanUserTargetForm}
     */
    public ChunMiaoPlanUserTargetForm queryChunMiaoTarget(Long idCode, Integer dateForYear){
        Year year = new Year(String.valueOf(dateForYear));
        Integer startDayInt = DateUtil.getDayIntByLocalDate(year.getYearStartDate());
        Integer endDayInt = DateUtil.getDayIntByLocalDate(year.getYearEndDate());
        List<String> keys = Arrays.stream(ChunMiaoTargetEnum.values()).map(ChunMiaoTargetEnum::getKey).collect(Collectors.toList());
        List<PerformanceObjective> performanceObjectiveList = performanceObjectiveRepository.getByObjectIdAndKeysAndType(new PerformanceObjectiveObjectId(idCode), keys, PerformanceObjectiveTypeEnum.CHUN_MIAO_PLAN_USER, startDayInt, endDayInt);
        if (CollectionUtils.isEmpty(performanceObjectiveList)){
            return null;
        }
        ChunMiaoPlanUserTargetForm res = new ChunMiaoPlanUserTargetForm(idCode, dateForYear);
        performanceObjectiveList.forEach(v -> {
            if (v.getKey().equals(ChunMiaoTargetEnum.PROFIT_TARGET.getKey())) {
                res.setProfitTarget(v.getValue().longValue());
            }
            if (v.getKey().equals(ChunMiaoTargetEnum.UPGRADE_TARGET.getKey())) {
                res.setUpgradeTarget(v.getValue().intValue());
            }
            if (v.getKey().equals(ChunMiaoTargetEnum.DEALER_PULL_TARGET.getKey())) {
                res.setDealerPullTarget(v.getValue().longValue());
            }
            if (v.getKey().equals(ChunMiaoTargetEnum.SVIP_PULL_TARGET.getKey())) {
                res.setSvipPullTarget(v.getValue().longValue());
            }
            if (v.getKey().equals(ChunMiaoTargetEnum.VVIP_PULL_TARGET.getKey())) {
                res.setVvipPullTarget(v.getValue().longValue());
            }
            if (v.getKey().equals(ChunMiaoTargetEnum.CROWD_DEALER_CUT_TARGET.getKey())) {
                res.setCrowdDealerCntTarget(v.getValue().longValue());
            }
        });
        return res;
    }

    public TableVO getCommonListByPage(GetPerformanceObjectiveCommonListForm form) {
        Integer pageSize = form.getPageSize();
        Integer pageIndex = form.getPageIndex();
        int offset = form.getOffset();

        TableVO table = new TableVO();
        List<ColumnVO> header = List.of(
                ColumnVO.of("secIdCode", "用户（ID）", false),
                ColumnVO.of("target", "目标", false)
        );
        table.setHeader(header);

        if (StringUtils.isEmpty(form.getTime())) {
            return table;
        }
        Integer startTime = getStartTime(form.getTime());
        Integer endTime = getEndTime(form.getTime());

        int total = performanceObjectiveRepository.getCommonListTotal(startTime, endTime, form.getChiefId(), PerformanceObjectiveTypeEnum.GEN_SEC.getCode(), form.getSecIdCode());

        Map<Long, List<String>> map = new HashMap<>();

        if (offset <= total) {
            List<PerformanceObjectiveObjectId> objectIdList = performanceObjectiveRepository.getObjectIdList(startTime, endTime, form.getChiefId(), PerformanceObjectiveTypeEnum.GEN_SEC.getCode(), form.getSecIdCode(), offset, pageSize);
            List<PerformanceObjective> performanceObjectiveList = performanceObjectiveRepository.getByObjectIdAndType(objectIdList, PerformanceObjectiveTypeEnum.GEN_SEC, startTime, endTime);
            for (PerformanceObjective performanceObjective : performanceObjectiveList) {
                long secIdCode = performanceObjective.getObjectId().getValue();
                if (map.containsKey(secIdCode)) {
                    List<String> targetList = map.get(secIdCode);
                    targetList.add(String.format("%s：%s", performanceObjective.getName(), performanceObjective.getValue()));
                } else {
                    List<String> targetList = Lists.newArrayList();
                    targetList.add(String.format("%s：%s", performanceObjective.getName(), performanceObjective.getValue()));
                    map.put(secIdCode, targetList);
                }
            }
        }

        Map<Long, UserDocument> userDocumentMap = getUserDocumentMap(map);

        List<Map<String, Object>> records = new ArrayList<>();
        for (Map.Entry<Long, List<String>> entry : map.entrySet()) {
            Map<String, Object> row = Maps.newHashMap();
            UserDocument userDocument = userDocumentMap.get(entry.getKey());
            row.put("secIdCode", buildSecIdCode(userDocument) + "（" + entry.getKey() + "）");
            row.put("target", StringUtils.join(entry.getValue(), "，"));
            records.add(row);
        }
        table.setRecords(records);
        table.setPage(PageResultVO.of(pageIndex, pageSize, total));
        return table;
    }

    private Integer getEndTime(String time) {
        if (DateUtil.QUARTER_SIGN.equalsIgnoreCase(String.valueOf(time.charAt(4)))) {
            LocalDateTime quarterMax = DateUtil.getQuarterMax(time);
            return DateUtil.getMonthInt(quarterMax);
        } else {
            return Integer.valueOf(time);
        }
    }

    private Integer getStartTime(String time) {
        if (DateUtil.QUARTER_SIGN.equalsIgnoreCase(String.valueOf(time.charAt(4)))) {
            LocalDateTime quarterMin = DateUtil.getQuarterMin(time);
            return DateUtil.getMonthInt(quarterMin);
        } else {
            return Integer.valueOf(time);
        }
    }

    private String buildSecIdCode(UserDocument userDocument) {
        String result = "";
        if (userDocument != null) {
            result = String.format("%s %s",
                    userDocument.getNickName(),
                    Optional.ofNullable(StarLevelEnum.parseByCode(userDocument.getStarLevel()))
                            .map(StarLevelEnum::getShortName).orElse(""));
        }
        return result;
    }

    public TableVO getPerformanceObjectiveListByPage(GetActivityPerformanceObjectiveListForm form) {
        Integer pageSize = form.getPageSize();
        Integer pageIndex = form.getPageIndex();
        int offset = form.getOffset();

        TableVO table = new TableVO();
        List<ColumnVO> header = List.of(
                ColumnVO.of("secIdCode", "用户（ID）", false),
                ColumnVO.of("target", "目标", false)
        );
        table.setHeader(header);

        MotivationActivityConfig activityConfig = activityConfigService.getByActivityId(form.getActivityId());
//        Long startTime = DateUtil.getSecondLong(activityConfig.getStartTime());
//        Long endTime = DateUtil.getSecondLong(activityConfig.getEndTime());

//        int total = performanceObjectiveRepository.getActivityListTotal(activityConfig.getActivityId(), form.getChiefId(), PerformanceObjectiveTypeEnum.GEN_SEC, form.getSecIdCode());

        Map<Long, List<String>> map = new HashMap<>();

//        if (offset <= total) {
//            List<PerformanceObjectiveObjectId> objectIdList = performanceObjectiveRepository.getRelationObjectIdList(activityConfig.getActivityId().getValue(), form.getChiefId(), PerformanceObjectiveTypeEnum.GEN_SEC, form.getSecIdCode(), offset, pageSize);
//            List<PerformanceObjective> performanceObjectiveList = performanceObjectiveRepository.getByObjectIdAndType(objectIdList, PerformanceObjectiveTypeEnum.GEN_SEC, startTime, endTime);
//            for (PerformanceObjective performanceObjective : performanceObjectiveList) {
//                long secIdCode = performanceObjective.getObjectId().getValue();
//                if (map.containsKey(secIdCode)) {
//                    List<String> targetList = map.get(secIdCode);
//                    targetList.add(String.format("%s：%s", performanceObjective.getName(), performanceObjective.getValue()));
//                } else {
//                    List<String> targetList = Lists.newArrayList();
//                    targetList.add(String.format("%s：%s", performanceObjective.getName(), performanceObjective.getValue()));
//                    map.put(secIdCode, targetList);
//                }
//            }
//        }

        Map<Long, UserDocument> userDocumentMap = getUserDocumentMap(map);

        List<Map<String, Object>> records = new ArrayList<>();
        for (Map.Entry<Long, List<String>> entry : map.entrySet()) {
            Map<String, Object> row = Maps.newHashMap();
            UserDocument userDocument = userDocumentMap.get(entry.getKey());
            row.put("secIdCode", buildSecIdCode(userDocument) + "（" + entry.getKey() + "）");
            row.put("target", StringUtils.join(entry.getValue(), "，"));
            records.add(row);
        }
        table.setRecords(records);
        table.setPage(PageResultVO.of(pageIndex, pageSize, 0));
        return table;
    }

    private Map<Long, UserDocument> getUserDocumentMap(Map<Long, List<String>> map) {
        List<UserIdCode> userIdCodes = map.keySet().stream()
                .map(UserIdCode::new)
                .collect(Collectors.toList());

        List<UserDocument> userDocumentList = userDocumentService.findByIds(userIdCodes);

        return userDocumentList.stream()
                .collect(Collectors.toMap(UserDocument::getIdCode, u -> u, (m1, m2) -> m1));
    }

    public TableVO exportPerformanceObjective(GetPerformanceObjectiveCommonListForm form) {
        Integer pageSize = form.getPageSize();
        Integer pageIndex = form.getPageIndex();
        int offset = form.getOffset();

        TableVO table = new TableVO();
        List<ColumnVO> header = List.of(
                ColumnVO.of("time", "日期", false),
                ColumnVO.of("secIdCode", "SEC用户ID", false),
                ColumnVO.of("name", "目标名称", false),
                ColumnVO.of("value", "目标值", false)
        );
        table.setHeader(header);

        if (StringUtils.isEmpty(form.getTime())) {
            return table;
        }
//        Long startTime = getStartTime(form.getTime());
//        Long endTime = getEndTime(form.getTime());

//        int total = performanceObjectiveRepository.getListTotal(startTime, endTime, form.getChiefId(), PerformanceObjectiveTypeEnum.GEN_SEC.getCode(), form.getSecIdCode());

        List<PerformanceObjective> performanceObjectiveList = Lists.newArrayList();
//        if (offset <= total) {
//            List<PerformanceObjectiveObjectId> objectIdList = performanceObjectiveRepository.getObjectIdList(startTime, endTime, form.getChiefId(), PerformanceObjectiveTypeEnum.GEN_SEC.getCode(), form.getSecIdCode(), offset, pageSize);
//            performanceObjectiveList = performanceObjectiveRepository.getByObjectIdAndType(objectIdList, PerformanceObjectiveTypeEnum.GEN_SEC, startTime, endTime);
//        }

        List<Map<String, Object>> records = new ArrayList<>();
//        for (PerformanceObjective performanceObjective : performanceObjectiveList) {
//            Map<String, Object> row = Maps.newHashMap();
//            row.put("time", DateUtil.getQuarterOrMonthStr(performanceObjective.getStartTime(), performanceObjective.getEndTime()));
//            row.put("secIdCode", performanceObjective.getObjectId().getValue());
//            row.put("name", performanceObjective.getName());
//            row.put("value", performanceObjective.getValue());
//            records.add(row);
//        }
        table.setRecords(records);
        table.setPage(PageResultVO.of(pageIndex, pageSize, 0));
        return table;
    }

    public List<String> getImportDesc() {
        List<String> result = Lists.newArrayList();
        result.add("说明：只支持EXCEL文件上传，相同日期目标导入将被覆盖更新");
        result.add("文件格式：日期、SEC ID、目标名称、目标值");
        result.add("日期格式：月份为202101，季度为2021Q1");
        result.add("目标名称可选：" + StringUtils.join(PerformanceObjectiveType.getTargetDescList(), "、"));
        return result;
    }
}
